package com.mumux.framework.ioc.core;

import com.google.common.collect.Lists;
import com.mumux.framework.ioc.bean.BeanDefinition;
import com.mumux.framework.ioc.bean.PropertyArg;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName XmlApplicationContext
 * Description TODO
 * @Author huangjuncong
 * @Date 2019/2/14 0014
 **/
@Slf4j
public class XmlApplicationContext extends BeanFactoryImpl {

    private String fileName;
    public XmlApplicationContext(String fileName) {
        this.fileName = fileName;
    }
    public void init(){
        loadFile();
    }
    private void loadFile(){

        List<BeanDefinition> beanDefinitions = getBeanDefinitions();
        if(beanDefinitions != null && !beanDefinitions.isEmpty()) {
            for (BeanDefinition beanDefinition : beanDefinitions) {
                registerBean(beanDefinition.getName(), beanDefinition);
            }
        }
    }

    private List<BeanDefinition> getBeanDefinitions(){
        try{
            InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = factory.newDocumentBuilder();
            Document doc = docBuilder.parse(is);
            Element root = doc.getDocumentElement();
            NodeList nodes = root.getChildNodes();
            ArrayList<BeanDefinition> beanDefinitionList = Lists.newArrayList();
            // 遍历 <bean> 标签
            for (int i = 0; i < nodes.getLength(); i++) {
                Node node = nodes.item(i);
                if (node instanceof Element) {
                    Element ele = (Element) node;
                    String id = ele.getAttribute("id");
                    String className = ele.getAttribute("class");
                    BeanDefinition beanDefinition = BeanDefinition.class.newInstance();
                    beanDefinition.setName(id);
                    beanDefinition.setClassName(className);
                    NodeList propertyNodes = ele.getElementsByTagName("property");
                    ArrayList<PropertyArg> propertyArgs = new ArrayList<>();
                    for (int j = 0; j < propertyNodes.getLength(); j++) {
                        Node propertyNode = propertyNodes.item(j);
                        if (propertyNode instanceof Element) {
                            PropertyArg propertyArg = PropertyArg.class.newInstance();
                            Element propertyElement = (Element) propertyNode;
                            String name = propertyElement.getAttribute("name");
                            propertyArg.setName(name);
                            String value = propertyElement.getAttribute("value");
                            if (StringUtils.isNotBlank(value)) {
                                propertyArg.setValue(value);
                            }
                            String ref = propertyElement.getAttribute("ref");
                            if (StringUtils.isNotBlank(ref)) {
                                propertyArg.setRef(ref);
                            }
                            propertyArgs.add(propertyArg);
                        }
                    }
                    beanDefinition.setPropertyArgs(propertyArgs);
                    beanDefinitionList.add(beanDefinition);
                }
            }
            return beanDefinitionList;
        }catch (Exception e){
            log.error("配置文件解析失败",e);
        }
        return null;
    }


}
